<?php
/**
 * 유틸리티 - XML
 *
 * <code>
 * $utilXml = new utilXml();
 * $utilXml->load($sSampleXmlFile);
 * </code>
 *
 * @package util
 *
 * @author jylee3@simplexi.com
 * @version 1.0
 */
class utilXml extends DOMDocument
{
    /**
     * DOMXPath Instance
     * @var DOMXPath
     */
    public $domXPath;

    public function __construct($sVersion='1.0', $sEncoding='UTF-8')
    {
        parent::__construct($sVersion, $sEncoding);
    }

    /**
     * XPath 조회
     *
     * <code>
     * $domNodeList = $utilXml->query('//entry');
     * </code>
     *
     * @param    String    $sExpression    XPath 문자식
     * @param    DOMNode $contextnode    대상 노드(DOMXPath->query 참고)
     *
     * @return     DOMNodeList
     */
    public function query($sExpression, DOMNode $contextnode=null)
    {
        $this->initDOMXPath();

        return is_null($contextnode)? $this->domXPath->query($sExpression) : $this->domXPath->query($sExpression, $contextnode);
    }

    /**
     * 지정된 DOM 객체에서 태그 이름에 대한 DOMElement 탐색 후 반환
     *
     * <code>
     * $domElement = $utilXml->nodeFind('title');
     * </code>
     *
     * @param    String    $sNodeName    대상 노드 이름
     * @param    Mixed    $nodeObject    대상 객체, 지정하지 않을경우 $this->childNodes
     *
     * @return    Mixed    DOMNode|DOMElement|Boolean(false)
     */
    public function domFind($sNodeName, $nodeObject=null)
    {
        if (is_null($nodeObject)) {
            $nodeObject = $this;
            $sObjectType = 'domdocument';
        } else {
            $sObjectType = strtolower(get_class($nodeObject));
        }

        switch ($sObjectType) {
            case 'domdocument' :
                return $this->domFindByNodeList($sNodeName, $nodeObject->childNodes);
                break;
            case 'domnodelist' :
                return $this->domFindByNodeList($sNodeName, $nodeObject);
                break;
        }

        return false;
    }

    /**
     * DOMNodeList에서 태그 이름에 대한 DOMElement 탐색 후 반환
     *
     * @param    String    $sNodeName
     * @param    DOMNodeList    $nodeList
     *
     * @return    Mixed    DOMNode|DOMElement|Boolean(false)
     */
    protected function domFindByNodeList($sNodeName, DOMNodeList $nodeList)
    {
        for ($i=0; $i<$nodeList->length; $i++) {
            if (strcasecmp($nodeList->item($i)->nodeName, $sNodeName)==0) {
                return $nodeList->item($i);
            }

            if ($nodeList->item($i)->hasChildNodes()) {
                $mResult = $this->domFindByNodeList($sNodeName, $nodeList->item($i)->childNodes);

                if ($mResult instanceof DOMNode) {
                    return $mResult;
                }
            }
        }

        return false;
    }

    /**
     * DOMXPath 초기화
     *
     * @return    void
     */
    protected function initDOMXPath()
    {
        if (!$this->domXPath instanceof DOMXPath) {
            $this->domXPath = new DOMXPath($this);
        }
    }
}
